a11y: Unrealize ATContext on dispose()
authorEmmanuele Bassi <ebassi@gnome.org>
Tue, 10 Nov 2020 17:18:55 +0000 (17:18 +0000)
committerEmmanuele Bassi <ebassi@gnome.org>
Wed, 11 Nov 2020 18:33:15 +0000 (18:33 +0000)
By unrealizing the context we avoid additional work during the dispose
phase, in case widget code updates the accessible state. We use
GtkAccessible's API, to ensure we unrealize the right ATContext, instead
of the one we store inside GtkWidgetPrivate.

We drop the ATContext instance inside GtkWidget during finalization, to
mop up eventual vivifications there.

gtk/gtkwidget.c

index c29cc88ec0cb8921b4c951c783db57c42530cddf..48a394a766a347633340af36003440263f372e46 100644 (file)
@@ -7028,6 +7028,7 @@ gtk_widget_dispose (GObject *object)
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
   GSList *sizegroups;
   GtkActionMuxer *muxer;
+  GtkATContext *at_context;
 
   muxer = g_object_get_qdata (G_OBJECT (widget), quark_action_muxer);
   if (muxer != NULL)
@@ -7050,8 +7051,6 @@ gtk_widget_dispose (GObject *object)
     gtk_layout_manager_set_widget (priv->layout_manager, NULL);
   g_clear_object (&priv->layout_manager);
 
-  g_clear_object (&priv->at_context);
-
   priv->visible = FALSE;
   if (_gtk_widget_get_realized (widget))
     gtk_widget_unrealize (widget);
@@ -7076,6 +7075,10 @@ gtk_widget_dispose (GObject *object)
       gtk_size_group_remove_widget (size_group, widget);
     }
 
+  at_context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
+  if (at_context != NULL)
+    gtk_at_context_unrealize (at_context);
+
   g_object_set_qdata (object, quark_action_muxer, NULL);
 
   G_OBJECT_CLASS (gtk_widget_parent_class)->dispose (object);
@@ -7237,6 +7240,7 @@ gtk_widget_finalize (GObject *object)
   g_object_unref (priv->cssnode);
 
   g_clear_object (&priv->context);
+  g_clear_object (&priv->at_context);
 
   _gtk_size_request_cache_free (&priv->requests);